﻿unit SysManageModel;

interface

uses
  FastMM4,
  FastMove,
  System.SysUtils,
  System.Classes,
  System.Types,
  Winapi.Windows,
  Data.DB,
  Data.Win.ADODB,
  Datasnap.DBClient,
  Datasnap.Provider,
  {$IFDEF UNICODE}
  AnsiStrings,
  {$ENDIF }
  QBParcel,
  DllSpread,
  Generics.Collections,
  DateUtils,
  QJson,
  UserConnection,
  DBAccessor,
  DllPlugin,
  StrUtils,
  SKSOFTComm;

type

  TSysManageModel = class(TObject)
  public 
    const cModuleKey='SysManage'; 
    const cTblName ='sys_manage';
    const cBaseView = 'view_sys_manage';
    const cObjNameKey='ObjName';
    const cObjGUIDKey='ObjGUID';
    const cObjItemsKey='Items';
    const cCdsModelKey='CdsModel';
    
    class function GetCountSQL(const iCondition:string; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;
    class function GetQuerySQL(const iCondition:string; const dOrderBy:string=''; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;
    class function GetPageQuerySQL(const iPageNo,iPageSize:Integer; const iCondition,iOrderBy:string; const dLoadMode:eDBLoadMode=eDBLoadMode.dblmTable):string;

    const cManageIdKey='manage_id';
    const cManageTypeKey='manage_type';
    const cManageIsSystemKey='manage_is_system';
    const cManageDescKey='manage_desc';
    const cManageSortNoKey='manage_sort_no';
    const cManageFileSizeKey='manage_file_size';
    const cManageFileTypeKey='manage_file_type';
    const cManageFileMd5Key='manage_file_md5';
    const cManageFileVersionKey='manage_file_version';
    const cManageFileStrKey='manage_file_str';
    const cTimeStampKey='time_stamp';
  end;
  
  TSysManage = class(TObject)
  private    
    fManageId:string;
    fManageType:Integer;
    fManageIsSystem:Boolean;
    fManageDesc:string;
    fManageSortNo:Integer;
    fManageFileSize:Integer;
    fManageFileType:string;
    fManageFileMd5:string;
    fManageFileVersion:string;
    fManageFileStr:string;
    fTimeStamp:Int64;
    
  protected
    fObjGUID:string;
    fInitDate:TDateTime;
    fCdsModel:TClientDataSet;
    function ObjectToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    
  public
    constructor Create();overload;
    destructor Destroy;override;
    
    procedure ResetObject;
    
    function LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
    function SaveToStr():string;
    
    property ObjGUID:string read fObjGUID;
    property ManageId:string read fManageId write fManageId;
    property ManageType:Integer read fManageType write fManageType;
    property ManageIsSystem:Boolean read fManageIsSystem write fManageIsSystem;
    property ManageDesc:string read fManageDesc write fManageDesc;
    property ManageSortNo:Integer read fManageSortNo write fManageSortNo;
    property ManageFileSize:Integer read fManageFileSize write fManageFileSize;
    property ManageFileType:string read fManageFileType write fManageFileType;
    property ManageFileMd5:string read fManageFileMd5 write fManageFileMd5;
    property ManageFileVersion:string read fManageFileVersion write fManageFileVersion;
    property ManageFileStr:string read fManageFileStr write fManageFileStr;
    property TimeStamp:Int64 read fTimeStamp write fTimeStamp;
  end;

  TSysManageList = class(TDictionary<string,TSysManage>)
  private
    fCdsModel:TClientDataSet;
    fSortKeys:TStrings;
    
  public
    constructor Create();overload;
    destructor Destroy;override;
    
    procedure ResetObject;
    
    function LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
    function LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
    function SaveToStr():string;
    
    function FindByKey(const iKey:string):TSysManage;
    function IsExist(iKey:string):Boolean;
    function Add(const iItem:TSysManage):string;
    function Delete(const iKey:string):Boolean;
    function Remove(const iKey:string):TSysManage;
    procedure Clear;
    
    property SortKeys:TStrings read fSortKeys write fSortKeys;
  end;

implementation

class function TSysManageModel.GetCountSQL(const iCondition:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSysManageModel.cTblName;
    dblmTable: ReadName:=TSysManageModel.cTblName;
    dblmView: ReadName:=TSysManageModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin
    Result:=Format(string('SELECT COUNT(*) AS ''COUNT'' FROM %s;'),[ReadName]);
  end else begin
    Result:=Format(string('SELECT COUNT(*) AS ''COUNT'' FROM %s WHERE %s;'),[ReadName,iCondition]);
  end;
end;

class function TSysManageModel.GetQuerySQL(const iCondition:string; const dOrderBy:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSysManageModel.cTblName;
    dblmTable: ReadName:=TSysManageModel.cTblName;
    dblmView: ReadName:=TSysManageModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin
    Result:=Format(string('SELECT * FROM %s %s;'),[ReadName,
                                                 IfThen(SameStr(dOrderBy,EmptyStr),'','ORDER BY '+dOrderBy)]);
  end else begin
    Result:=Format(string('SELECT * FROM %s WHERE %s %s;'),[ReadName,iCondition,
                                                            IfThen(SameStr(dOrderBy,EmptyStr),'','ORDER BY '+dOrderBy)]);
  end;
end;

class function TSysManageModel.GetPageQuerySQL(const iPageNo,iPageSize:Integer; const iCondition,iOrderBy:string; const dLoadMode:eDBLoadMode):string;
var
  ReadName:string;
begin
  case dLoadMode of
    dblmNone: ReadName:=TSysManageModel.cTblName;
    dblmTable: ReadName:=TSysManageModel.cTblName;
    dblmView: ReadName:=TSysManageModel.cBaseView;
  end;
  
  if SameStr(Trim(iCondition),EmptyStr) then
  begin      
    Result:=Format(string('SELECT * FROM %s'),[ReadName]);
  end else begin
    Result:=Format(string('SELECT * FROM %s WHERE %s'),[ReadName,iCondition]);
  end;
  Result:=Format(string('SELECT TOP %d * FROM (SELECT row_number() OVER(ORDER BY %s) AS _row_no_,* FROM (%s) AS A) AS B WHERE _row_no_>%d ORDER BY _row_no_'),
                  [iPageSize,
                  IfThen(SameStr(Trim(iOrderBy),EmptyStr),'',iOrderBy),
                  Result,
                  (iPageNo-1)*iPageSize]);
end;

constructor TSysManage.Create();
begin
  inherited Create;
  fInitDate:=EncodeDateTime( 1899, 12, 30, 0, 0, 0, 0 );
  fCdsModel:=TClientDataSet.Create(nil);
  ResetObject;
end;

destructor TSysManage.Destroy;
begin
  FreeAndNil(fCdsModel);
  inherited Destroy;
end;

procedure TSysManage.ResetObject;
begin
  fObjGUID:=TSKSOFTComm.GetGUID;
  fManageId:=EmptyStr;
  fManageType:=-1;
  fManageIsSystem:=False;
  fManageDesc:=EmptyStr;
  fManageSortNo:=-1;
  fManageFileSize:=-1;
  fManageFileType:=EmptyStr;
  fManageFileMd5:=EmptyStr;
  fManageFileVersion:=EmptyStr;
  fManageFileStr:=EmptyStr;
  fTimeStamp:=-1;
end;

function TSysManage.LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    ResetObject;
    if (iCds.FindField(TSysManageModel.cManageIdKey)<>nil) then
    begin
      fManageId:=iCds.FieldByName(TSysManageModel.cManageIdKey).AsString;     
      fObjGUID:=TSKSOFTComm.SetObjGUID(fManageId);
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageTypeKey)<>nil) then
    begin
      fManageType:=iCds.FieldByName(TSysManageModel.cManageTypeKey).AsInteger;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageTypeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageIsSystemKey)<>nil) then
    begin
      fManageIsSystem:=iCds.FieldByName(TSysManageModel.cManageIsSystemKey).AsBoolean;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageIsSystemKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageDescKey)<>nil) then
    begin
      fManageDesc:=iCds.FieldByName(TSysManageModel.cManageDescKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageDescKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageSortNoKey)<>nil) then
    begin
      fManageSortNo:=iCds.FieldByName(TSysManageModel.cManageSortNoKey).AsInteger;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageSortNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileSizeKey)<>nil) then
    begin
      fManageFileSize:=iCds.FieldByName(TSysManageModel.cManageFileSizeKey).AsInteger;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileSizeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileTypeKey)<>nil) then
    begin
      fManageFileType:=iCds.FieldByName(TSysManageModel.cManageFileTypeKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileTypeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileMd5Key)<>nil) then
    begin
      fManageFileMd5:=iCds.FieldByName(TSysManageModel.cManageFileMd5Key).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileMd5Key]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileVersionKey)<>nil) then
    begin
      fManageFileVersion:=iCds.FieldByName(TSysManageModel.cManageFileVersionKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileVersionKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileStrKey)<>nil) then
    begin
      fManageFileStr:=iCds.FieldByName(TSysManageModel.cManageFileStrKey).AsString;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileStrKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cTimeStampKey)<>nil) then
    begin
      fTimeStamp:=iCds.FieldByName(TSysManageModel.cTimeStampKey).AsLargeInt;     
    end else begin
      oError:=Format(string('%s装载错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cTimeStampKey]);
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.LoadFromCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysManage.ObjectToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    if (iCds.FindField(TSysManageModel.cManageIdKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageIdKey).AsString:=fManageId;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageIdKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageTypeKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageTypeKey).AsInteger:=fManageType;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageTypeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageIsSystemKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageIsSystemKey).AsBoolean:=fManageIsSystem;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageIsSystemKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageDescKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageDescKey).AsString:=fManageDesc;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageDescKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageSortNoKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageSortNoKey).AsInteger:=fManageSortNo;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageSortNoKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileSizeKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageFileSizeKey).AsInteger:=fManageFileSize;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileSizeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileTypeKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageFileTypeKey).AsString:=fManageFileType;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileTypeKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileMd5Key)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageFileMd5Key).AsString:=fManageFileMd5;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileMd5Key]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileVersionKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageFileVersionKey).AsString:=fManageFileVersion;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileVersionKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cManageFileStrKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cManageFileStrKey).AsString:=fManageFileStr;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cManageFileStrKey]);
      Result:=False;
      Exit;
    end;
    if (iCds.FindField(TSysManageModel.cTimeStampKey)<>nil) then
    begin
      iCds.FieldByName(TSysManageModel.cTimeStampKey).AsLargeInt:=fTimeStamp;     
    end else begin
      oError:=Format(string('%s对象转数据集错误:数据集中缺少%s字段!'),[Self.ClassName,TSysManageModel.cTimeStampKey]);
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.ObjectToCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysManage.SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
begin
  if (iCds<>nil) then
  begin
    iCds.Append;
    if ObjectToCDS(iCds,oError) then
    begin
      iCds.Post;
    end else begin
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用%s.SaveToCDS函数参数错误!错误内容:传入的Cds对象为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysManage.LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
var
  Json:TQJson;
  MemStream:TMemoryStream;
begin
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    if Json.TryParse(iJsonStr) then
    begin
      if (Json.ItemByName(TSysManageModel.cObjNameKey)<>nil) then
      begin
        if (Self.ClassName<>Json.ItemByName(TSysManageModel.cObjNameKey).AsString) then
        begin
          //oError:=Format(string('调用%s.LoadFromStr函数！错误内容:对象类名不匹配.'),[Self.ClassName]);
          //Result:=False;
          //Exit;
        end;
      end else begin
        oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性节点.'),[Self.ClassName,TSysManageModel.cObjNameKey]);
        Result:=False;
        Exit;
      end;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:解析Json失败.iJsonStr:%s'),[Self.ClassName,iJsonStr]);
      Result:=False;
      Exit;
    end;
    ResetObject;
      
    if (Json.ItemByName(TSysManageModel.cCdsModelKey)<>nil) and 
      not SameStr(Trim(Json.ItemByName(TSysManageModel.cCdsModelKey).AsString),EmptyStr) then
    begin
      TSKSOFTComm.Base64StrToMemStream(AnsiString(Json.ItemByName(TSysManageModel.cCdsModelKey).AsString),MemStream);
      if MemStream.Size>0 then
      begin
        fCdsModel.LoadFromStream(MemStream);
      end;
    end;
    
    if (Json.ItemByName(TSysManageModel.cObjGUIDKey)<>nil) and 
      not SameStr(Trim(Json.ItemByName(TSysManageModel.cObjGUIDKey).AsString),EmptyStr) then
    begin
      fObjGUID:=Json.ItemByName(TSysManageModel.cObjGUIDKey).AsString;
    end;
    
    if Json.ItemByName('ManageId')<>nil then
    begin
      fManageId:=Json.ItemByName('ManageId').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageId']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageType')<>nil then
    begin
      fManageType:=Json.ItemByName('ManageType').AsInteger;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageType']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageIsSystem')<>nil then
    begin
      fManageIsSystem:=Json.ItemByName('ManageIsSystem').AsBoolean;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageIsSystem']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageDesc')<>nil then
    begin
      fManageDesc:=Json.ItemByName('ManageDesc').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageDesc']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageSortNo')<>nil then
    begin
      fManageSortNo:=Json.ItemByName('ManageSortNo').AsInteger;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageSortNo']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageFileSize')<>nil then
    begin
      fManageFileSize:=Json.ItemByName('ManageFileSize').AsInteger;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageFileSize']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageFileType')<>nil then
    begin
      fManageFileType:=Json.ItemByName('ManageFileType').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageFileType']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageFileMd5')<>nil then
    begin
      fManageFileMd5:=Json.ItemByName('ManageFileMd5').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageFileMd5']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageFileVersion')<>nil then
    begin
      fManageFileVersion:=Json.ItemByName('ManageFileVersion').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageFileVersion']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('ManageFileStr')<>nil then
    begin
      fManageFileStr:=Json.ItemByName('ManageFileStr').AsString;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'ManageFileStr']);
      Result:=False;
      Exit;  
    end;
    if Json.ItemByName('TimeStamp')<>nil then
    begin
      fTimeStamp:=Json.ItemByName('TimeStamp').AsInt64;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数！错误内容:缺少%s属性.'),[Self.ClassName,'TimeStamp']);
      Result:=False;
      Exit;  
    end;
    
  finally
    Json.Free;
    MemStream.Free;
  end;
  Result:=True;
end;

function TSysManage.SaveToStr():string;
var
  Json:TQJson;
  MemStream:TMemoryStream;
begin
  Result:=EmptyStr;  
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create; 
  try
    Json.Add('ModuleKey').AsString:=TSysManageModel.cModuleKey;
    Json.Add(TSysManageModel.cObjNameKey).AsString:=Self.ClassName;
    
    fCdsModel.SaveToStream(MemStream);
    Json.Add(TSysManageModel.cCdsModelKey).AsString:=string(TSKSOFTComm.MemStreamToBase64Str(MemStream));
    
    Json.Add(TSysManageModel.cObjGUIDKey).AsString:=fObjGUID;
    Json.Add('ManageId').AsString:=fManageId;
    Json.Add('ManageType').AsInteger:=fManageType;
    Json.Add('ManageIsSystem').AsBoolean:=fManageIsSystem;
    Json.Add('ManageDesc').AsString:=fManageDesc;
    Json.Add('ManageSortNo').AsInteger:=fManageSortNo;
    Json.Add('ManageFileSize').AsInteger:=fManageFileSize;
    Json.Add('ManageFileType').AsString:=fManageFileType;
    Json.Add('ManageFileMd5').AsString:=fManageFileMd5;
    Json.Add('ManageFileVersion').AsString:=fManageFileVersion;
    Json.Add('ManageFileStr').AsString:=fManageFileStr;
    Json.Add('TimeStamp').AsInt64:=fTimeStamp;
    Result:=Json.AsString;
  finally
    Json.Free;
    MemStream.Free;
  end;
end;

constructor TSysManageList.Create();
begin
  inherited Create;
  fCdsModel:=TClientDataSet.Create(nil);
  fSortKeys:=TStringList.Create;
  ResetObject;
end;

destructor TSysManageList.Destroy;
begin
  FreeAndNil(fCdsModel);
  Clear;
  FreeAndNil(fSortKeys);
  inherited Destroy;
end;

procedure TSysManageList.ResetObject;
begin
  Clear;
end;

function TSysManageList.LoadFromCDS(const iCds:TClientDataSet; out oError:string):Boolean;
var
  Item:TSysManage;
begin
  ResetObject;
  if iCds<>nil then
  begin
    iCds.First;
    while not iCds.Eof do
    begin
      Item:=TSysManage.Create;
      if Item.LoadFromCDS(iCds,oError) then
      begin
        if Add(Item)=EmptyStr then
        begin
          Item.Free;
          Result:=False;
          Exit;
        end;
      end else begin
        Result:=False;
        Exit;
      end;
      iCds.Next;
    end;
  end else begin
    oError:=Format(string('调用%s.LoadFromCDS函数参数错误! 错误内容传入的数据集为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysManageList.SaveToCDS(const iCds:TClientDataSet; out oError:string):Boolean;
var
  Key:string;
begin
  if (iCds<>nil) then
  begin
  for Key in fSortKeys do
  begin
    iCds.Append;
    if Items[Key].ObjectToCDS(iCds,oError) then
    begin
      iCds.Post;
    end else begin
      Result:=False;
      Exit;
    end;
  end;
  end else begin
    oError:=Format(string('调用%s.SaveToCDS函数参数错误! 错误内容:传入的数据集为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysManageList.LoadFromStr(const iJsonStr:string; out oError:string):Boolean;
var
  Json,ItemJson,ArrayJson:TQJson;
  Item:TSysManage;
  MemStream:TMemoryStream;
begin
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    if Json.TryParse(iJsonStr) then
    begin
      if (Json.ItemByName(TSysManageModel.cObjNameKey)<>nil) then
      begin
        if (Self.ClassName<>Json.ItemByName(TSysManageModel.cObjNameKey).AsString) then
        begin
          //oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:对象类名不匹配.'),[Self.ClassName]);
          //Result:=False;
          //Exit;
        end;
      end else begin
        oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:缺少%s属性节点.'),[Self.ClassName,TSysManageModel.cObjNameKey]);
        Result:=False;
        Exit;
      end;
    end else begin
      oError:=Format(string('调用%s.LoadFromStr函数参数错误! 错误内容:解析Json失败.iJsonStr:%s'),[Self.ClassName,iJsonStr]);
      Result:=False;
      Exit;
    end;
    if (Json.ItemByName(TSysManageModel.cObjItemsKey)<>nil) and
      (Json.ItemByName(TSysManageModel.cObjItemsKey).IsArray) then
    begin
      ResetObject;
      if Json.ItemByName(TSysManageModel.cCdsModelKey)<>nil then
      begin
        TSKSOFTComm.Base64StrToMemStream(AnsiString(Json.ItemByName(TSysManageModel.cCdsModelKey).AsString),MemStream);
        if MemStream.Size>0 then
        begin
          fCdsModel.LoadFromStream(MemStream);
        end;
      end;
      ArrayJson:=Json.ItemByName(TSysManageModel.cObjItemsKey);
      for ItemJson in ArrayJson do
      begin
        Item:=TSysManage.Create;
        Item.LoadFromStr(ItemJson.AsString,oError);
        if Add(Item)=EmptyStr then
        begin
          Item.Free;
          Result:=False;
          Exit;
        end;
      end;
    end else begin
      Result:=False;
      Exit;
    end;
  finally
    Json.Free;
    MemStream.Free;
  end;
  Result:=True;
end;

function TSysManageList.SaveToStr():string;
var
  Key:string;
  Json,ItemJson,ArrayJson:TQJson;
  MemStream:TMemoryStream;
begin
  Result:=EmptyStr;
  Json:=TQJson.Create;
  MemStream:=TMemoryStream.Create;
  try
    Json.Add(TSysManageModel.cObjNameKey).AsString:=Self.ClassName;
    fCdsModel.SaveToStream(MemStream);
    Json.Add(TSysManageModel.cCdsModelKey).AsString:=string(TSKSOFTComm.MemStreamToBase64Str(MemStream));

    ArrayJson:=Json.Add(TSysManageModel.cObjItemsKey,jdtArray);
    for Key in fSortKeys do
    begin
      ItemJson:=TQJson.Create;
      if ItemJson.TryParse(Items[Key].SaveToStr()) then
      begin
        ArrayJson.Add(ItemJson);
      end else begin
        ItemJson.Free;
      end;
    end;
    Result:=Json.AsString;
  finally
    Json.Free;
    MemStream.Free;
  end;
end;

function TSysManageList.FindByKey(const iKey:string):TSysManage;
var
  Item:TSysManage;
begin
  if TryGetValue(iKey,Item) then
  begin
    Result:=Item;
  end else begin
    Result:=nil;
  end;
end;

function TSysManageList.IsExist(iKey:string):Boolean;
var
  Item:TSysManage;
begin
  Result:= TryGetValue(iKey,Item);
end;

function TSysManageList.Add(const iItem:TSysManage):string;
begin
  if iItem.ObjGUID<>EmptyStr then
  begin
    inherited Add(iItem.ObjGUID,iItem);
    Result:=iItem.ObjGUID;
    fSortKeys.Add(iItem.ObjGUID);
  end else begin
    Result:=EmptyStr;
  end;
end;

function TSysManageList.Delete(const iKey:string):Boolean;
var
  Ops:Integer;
begin
  if ContainsKey(iKey) then
  begin
    Remove(iKey).Free;
    Ops:=fSortKeys.IndexOf(iKey);
    if Ops<>-1 then
    begin
      fSortKeys.Delete(Ops);
    end;
    Result:=True;
  end else begin
    Result:=False;
  end;
end;

function TSysManageList.Remove(const iKey:string):TSysManage;
var
  Ops:Integer;
begin
  if ContainsKey(iKey) then
  begin
    Result:=Items[iKey];
    Ops:=fSortKeys.IndexOf(iKey);
    if Ops<>-1 then
    begin
      fSortKeys.Delete(Ops);
    end;
    inherited Remove(iKey);
  end else begin
    Result:=nil;
  end;
end;

procedure TSysManageList.Clear;
var
  Key:string;
begin
  for Key in Keys do
  begin
    if Items[Key]<>nil then
    begin
      Items[Key].Free;
    end;
  end;
  fSortKeys.Clear;
  inherited Clear;
end;

end.
